package com.eken.bgm.model.message;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MessageBuffer {
	public final static String ERROR_MESSAGE = "Error";
	public final static String SUCCESS_MESSAGE = "Success";
	
	public static enum MessageType { ERROR, SUCCESS };
	
	private static MessageBuffer theInstance = null;
	
	public static MessageBuffer getInstance() {
		if(theInstance == null) {
			theInstance = new MessageBuffer();
		}
		
		return theInstance;
	}
	
	private PropertyChangeSupport listeners;
	
	private Map<MessageType, List<String>> buffer;
	
	private MessageBuffer() {
		this.buffer = new HashMap<MessageType, List<String>>();
		this.listeners = new PropertyChangeSupport(this);
	}
	
	/**
	 * Adds a listener to the message buffer. The listener will
	 * receive messages appended to the buffer.
	 * @param listener	the listener
	 */
	public void addListener(PropertyChangeListener listener) {
		this.listeners.addPropertyChangeListener(listener);
	}

	/**
	 * Append an message of certain type to the message buffer.
	 * @param type	The type of the message
	 * @param msg	The message
	 */
	public void append(MessageType type, String msg) {
		List<String> messageBuffer;
		if((messageBuffer = this.buffer.get(type)) == null) {
			messageBuffer = new ArrayList<String>();
			this.buffer.put(type, messageBuffer);
		}
		
		messageBuffer.add(msg);
		
		String tMessageType = type == MessageType.ERROR ? ERROR_MESSAGE : SUCCESS_MESSAGE;
		
		this.listeners.firePropertyChange(tMessageType, null, msg);
	}

	/**
	 * Clears the buffer.
	 */
	public void clear() {
		this.buffer.clear();
	}

	/**
	 * Returns the whole buffer as an array.
	 * @return	the whole buffer
	 */
	public String[] getMessages() {
		List<String> messages = new ArrayList<String>();
		for(List<String> l : this.buffer.values()) {
			messages.addAll(l);
		}
		
		return messages.toArray(new String[messages.size()]);
	}

	/**
	 * Returns an array of messages associated to the given
	 * MessageType.
	 * @param type	The type of the messages
	 * @return		An array of messages of the given type.
	 */
	public String[] getMessages(MessageType type) {
		List<String> messages = new ArrayList<String>();
		messages.addAll(this.buffer.get(type));
		
		return messages.toArray(new String[messages.size()]);
	}
	
	/**
	 * The number of messages in the message buffer
	 */
	public int size() {
		return this.buffer.size();
	}
}
